Skip to content

test: re-derive the numbers and reasons four guards document - #2116

Merged
laurentiu021 merged 1 commit into
mainfrom
test/re-derive-stale-guard-prose
Sep 4, 2026
Merged

test: re-derive the numbers and reasons four guards document#2116
laurentiu021 merged 1 commit into
mainfrom
test/re-derive-stale-guard-prose

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

Closes #2110.

Four guards documented numbers or reasons that no longer matched the code they protect. None was failing, which is the point: a guard whose prose is wrong still passes, and the next reader takes its derivation as current fact.

1. SetCustom's slice ran ten times past its own body

EveryThemeEntryPoint_GoesThroughTheLegibilityCorrection bounded each method with "up to the next member declaration", implemented as find the next public, and only fall back to private if there is none. For a method followed by private members that skips over them to a later public one.

Measured: SetCustom's slice was 6727 characters against a real body of 675, swallowing IsDarkBackground, ApplyShade, Shade and Legible. Nothing in that region calls ApplyShade() today, so Assert.Contains("ApplyShade();", body) was still being satisfied by SetCustom's own call — but one added call anywhere in those six kilobytes and the guard could no longer tell whether SetCustom still does it.

Now brace-matched, via the BalancedBlock helper added in #2112.

2. Its justification was three fixes out of date

It said the assertion is on source rather than by calling the method "because SetCustom ends in Save(), which writes the user's real theme file". True before #1741 made SettingsPath redirectable — and false since: ThemeServiceTests calls SetCustom for real against a temp directory. The guard is still worth having, for a different reason (an entry point nobody wrote a test for), and now says so.

3. The admin-banner counts

Remarks and failure message both quoted "27 views", "27 of 27" and "29 of 29" — three numbers that disagreed with each other and with the tree. Re-derived: 62 banners across 31 views, 31 pairs, all on CornerRadius="12" Padding="12,8". The failure message now computes the count from what it parsed instead of quoting a remembered one.

4. The sidebar-label budget charged leaf rows for a deleted glyph column

The derivation subtracted "the 13px glyph and its 10px margin", leaving 155px. Leaf rows carry no glyph — NavItem has no such member, and the only two glyph bindings left in MainWindow.xaml are the group header's own and the single-item row reading its group's. A leaf label's real budget is 220 - 28 - 14 = 178px, about 27 characters. The asserted budgets (21 and 23) come from the longest shipping labels, not the pixel math, so they are unchanged.

5. The PR checklist omitted the one gate that fails after the merge

auto-release.yml requires the newest CHANGELOG heading to be dated today in UTC, and it runs after the squash merge, when the branch is gone. A stale date fails the release rather than the pull request — the workflow's own comment says it has published yesterday's date twice. The checklist said nothing about it.

ThePullRequestChecklist_AsksForWhatCiEnforces could not see the omission either: it anchors on ci.yml's step names, and this gate is not in ci.yml. It now reads auto-release.yml too and requires the release-only section to mention UTC.

Also: private workflow wording out of tracked files

Four tracked files described a particular two-machine development setup — "which happens on the other workstation", "verified on the laptop workstation", "not the build box". Rewritten to say what they mean ("needs the app actually running") in ArchitectureTests.cs, SidebarSelectionContractTests.cs, AudioPolicyConfigTests.cs and ARCHITECTURE.md. Zero occurrences remain in the tree; the same pass was already applied to 23 issue and PR bodies.

Verification

Mutation proof, both files restored byte-for-byte:

Mutation Result
the checklist loses its today-in-UTC item RED on ThePullRequestChecklist_AsksForWhatCiEnforces, and only that test
SetCustom drops ApplyShade() and a member in the previously-swallowed region gains one RED on EveryThemeEntryPoint_GoesThroughTheLegibilityCorrection, and only that test

The second mutation is deliberately the case the old slice would have accepted. Baseline and post-restore 2 green, 0 red.

107 cases green across ArchitectureTests, SidebarSelectionContractTests, AudioPolicyConfigTests and ThemeServiceTests. Builds 0 errors / 0 warnings, dotnet format --verify-no-changes clean on both projects. test: — no version bump, no CHANGELOG entry, no release.

None of these was failing. That is the problem: a guard whose prose is wrong still
passes, and the next reader takes its derivation as fact.

EveryThemeEntryPoint bounded each method by "the next member declaration", looking
for the next public and only falling back to private when there was none -- so a
method followed by private members had its slice run past them. SetCustom measured
6727 characters against a real body of 675, swallowing four members. Nothing there
calls ApplyShade() today, so the assertion was still honest, but one added call and
it could no longer tell. Now brace-matched.

Its justification also said SetCustom cannot be called because Save() writes the
user's real theme file. True before #1741 made SettingsPath redirectable, false
since -- ThemeServiceTests calls it against a temp directory. The reason is coverage
of an untested entry point, and now says that.

The admin-banner guard quoted 27 views / 27 of 27 / 29 of 29, three numbers that
disagreed with each other and the tree. Re-derived: 62 banners across 31 views. The
failure message now computes the count instead of quoting one.

The label budget subtracted 23px for a glyph column leaf rows no longer have. Real
budget 178px, about 27 characters. The asserted values come from the longest shipping
labels, so they are unchanged.

The PR checklist omitted auto-release's today-in-UTC date rule -- the only gate that
runs after the squash merge, which has published yesterday's date twice. The guard
could not see the omission because it reads ci.yml and that gate is elsewhere; it now
reads auto-release.yml too.

Also removes wording describing a particular two-machine development setup from four
tracked files.

Closes #2110
@laurentiu021
laurentiu021 merged commit 5cf47f3 into main Sep 4, 2026
5 checks passed
@laurentiu021
laurentiu021 deleted the test/re-derive-stale-guard-prose branch September 4, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Four guards document numbers and reasons that no longer match the code, and one slice is unbounded

1 participant